package app 
{
	import app.textures.DisplayType;
	import app.textures.TextureInfo;
	import app.textures.TextureInfoGroupe;
	import com.bit101.components.HBox;
	import com.bit101.components.VBox;
	import events.ModuleBottomEvent;
	import fl.controls.ScrollPolicy;
	import fl.controls.SliderDirection;
	import fl.controls.TileList;
	import fl.data.DataProvider;
	import fl.events.ScrollEvent;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextFormat;
	import gui.Binder;
	import gui.buttons.RadioButton;
	import gui.factory.StyleFactory;
	import gui.ScrollBar;
	import resources.Images;
	import utils.ErrorsCollector;
	import utils.Logger;
	/**
	 * ...
	 * @author Dmitriy Gaiduk
	 */
	/**
	 * When texture selected
	 */
	[Event(name = "TEXTURE_SELECTED", type = "events.ModuleBottomEvent")]
	public class ModuleBottom extends Sprite
	{
		private var _btnFacadeChoose:RadioButton;
		private var _btnTabletopChoose:RadioButton;
		private var _model:AppModel;
		private var _vBox:VBox = null;
		/**
		 * Radio buttons of textre groups
		 */
		private var _radioButtons:Vector.<RadioButton>;
		private const TREE_FACADE_GROUPE:String = "TREE_FACADE_GROUPE";
		private const TREE_TABLETOP_GROUPE:String = "TREE_TABLETOP_GROUPE";
		
		private var _tileList:TileList;
		private var _scrollBar:ScrollBar;
		private var _binderScrollBar:Binder;
		
		private var _moduleWidth:Number = 0;
		private var _moduleHeight:Number = 0;
		private var _textureBackground:DisplayObject;
		
		private var _currentTextureGroupeInfo:TextureInfoGroupe = null;
		
		public function ModuleBottom(model:AppModel) 
		{
			_model = model;
			addEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
		}
		
		private function handleAddedToStage(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
			initModule();
		}
		
		private function initModule():void 
		{
			_textureBackground = new BottomBarTextureBg();
			_textureBackground.x = 401;
			_textureBackground.y = StyleFactory.BOTTOM_MODULE_HEAD_HEIGHT;
			addChild(_textureBackground);

			
			_binderScrollBar = new Binder();
			var radBtnGroup:String = "ModuleBottomMain";
			var btnBox:HBox = new HBox(this, 0, 0);
			btnBox.spacing = 0;
			_btnFacadeChoose = new RadioButton();
			_btnFacadeChoose.groupName = radBtnGroup;
			StyleFactory.setRadioButtonStyle(_btnFacadeChoose, StyleFactory.BOTTOM_BAR_FACADE);
			btnBox.addChild(_btnFacadeChoose);
			_btnFacadeChoose.addEventListener(MouseEvent.CLICK, facadeChooseChange);
			
			_btnTabletopChoose = new RadioButton();
			_btnTabletopChoose.groupName = radBtnGroup;
			StyleFactory.setRadioButtonStyle(_btnTabletopChoose, StyleFactory.BOTTOM_BAR_TABLETOP);

			btnBox.addChild(_btnTabletopChoose);
			_btnTabletopChoose.addEventListener(MouseEvent.CLICK, tabletopChange);
			//_btnTabletopChoose.selected = true;
		}
		
		private function tabletopChange(e:Event):void 
		{
			//_btnTabletopChoose.removeEventListener(Event.CHANGE, tabletopChange);
			showHideTree(_model.tabletopTextures, _btnFacadeChoose.width, TREE_TABLETOP_GROUPE, _btnTabletopChoose);
		}
		
		private function facadeChooseChange(e:Event):void 
		{
			showHideTree(_model.facadeTextures, 0, TREE_FACADE_GROUPE, _btnFacadeChoose);
			//_btnFacadeChoose.removeEventListener(Event.CHANGE, facadeChooseChange);
		}
		
		private function groupIsAdded(group:String):Boolean {
			if (_radioButtons == null) {
				return false;
			}
			
			for (var i:int = 0; i < _radioButtons.length; i++) {
				if (_radioButtons[i].groupName == group) {
					return true;
					
				}
			}
			
			return false;
		}
		
		private function groupIsShow(group:String):Boolean {
			if (_radioButtons == null) {
				return false;
			}
			
			for (var i:int = 0; i < _radioButtons.length; i++) {
				if (_radioButtons[i].groupName == group) {
					if (_radioButtons[i].visible) {
						return true;
					}else {
						return false;
					}
					
				}
			}
			
			return false;
		}
		
		private function setVisibleGroupe(groupe:String, visibleGroupe:Boolean):void {
			if (_radioButtons == null) {
				return;
			}
			
			for (var i:int = 0; i < _radioButtons.length; i++) {
				if (_radioButtons[i].groupName == groupe) {
					_radioButtons[i].visible = visibleGroupe;
				}
			}
		}
		
		private function showHideTileTextures(groupe:String, toShow:Boolean):void {
			if (_radioButtons == null || _tileList == null) {
				return;
			}
			
			for (var i:int = 0; i < _radioButtons.length; i++) {
				if (_radioButtons[i].visible && _radioButtons[i].selected) {
					
					if (toShow && _radioButtons[i].groupName != groupe) {
						continue;
					}
					
					var textureGroupe:TextureInfoGroupe = _radioButtons[i].value as TextureInfoGroupe;
					if (textureGroupe == null)
					{
						ErrorsCollector.getInstance().collectError("Module bottom: radiobutton on showHideTileTextures. textureGroupe is NULL");
						return;
					}
					
					showTextureTileList(textureGroupe);
					
					return;
				}
			}
			
			if (toShow) {
				return;
			}
			
			_tileList.visible = false;
			_scrollBar.visible = false;
			
		}
		
		private function showHideTree(groups:Vector.<TextureInfoGroupe>, posX:Number, group:String, 
										sender:RadioButton):void
		{
			if (groupIsAdded(group)) {
				if (groupIsShow(group)) {
					sender.selected = false;
					setVisibleGroupe(group, false);
					showHideTileTextures(group, false);
				}else {
					sender.selected = true;
					setVisibleGroupe(group, true);
					showHideTileTextures(group, true);
				}
				return;
			}
			
			log("Create groupe: " + group);
			/*if (_vBox != null)
			{
				if(_vBox.parent != null)
				{
					
					_vBox.parent.removeChild(_vBox);
				}
			}
			if (_tileList != null)
			{
				if (_tileList.parent != null)
				{
					_tileList.parent.removeChild(_tileList);
				}else
				{
					ErrorsCollector.getInstance().collectError("Module bottom: tileList exist, but parent null");
					return;
				}
			}
			_tileList = null;
			
			for each(var radioBtn:RadioButton in _rbTextureGroups)
			{
				if (radioBtn.parent != null)
				{
					radioBtn.parent.removeChild(radioBtn);
				}
			}
			*/
			_vBox = new VBox(this);
			_vBox.spacing = 0;
			_vBox.y = _btnFacadeChoose.height;
			_vBox.x = posX;
			
			if(_radioButtons == null){
				_radioButtons = new Vector.<RadioButton>();
			}
			
			for each (var gr:TextureInfoGroupe in groups)
			{
				var rb:RadioButton = new RadioButton();
				rb.groupName = group;
				
				StyleFactory.setRadioButtonStyle(rb, gr.buttonStyle);
				//rb.label = gr.groupeName;
				rb.value = gr;
				//rb.addEventListener(Event.CHANGE, handleTextureGroupeSelected);
				rb.addEventListener(MouseEvent.CLICK, handleTextureGroupeSelected);
				_vBox.addChild(rb);
				_radioButtons.push(rb);
				if (groups.indexOf(gr) == 0)
				{
					//rb.selected = true;
				}
			}
		}
		
		private function getTextureGroupeSelected():TextureInfoGroupe
		{
			return _currentTextureGroupeInfo;
			/*
			if (_radioButtons == null)
			{
				return null;
			}
			var textureGroupe:TextureInfoGroupe = null;
			for each(var rb:RadioButton in _radioButtons)
			{
				if (rb.selected)
				{
					textureGroupe = rb.value as TextureInfoGroupe;
					break;
				}
			}
			return textureGroupe;*/
			
		}
		
		private function handleTextureGroupeSelected(e:Event):void 
		{
			// show textures
			var radBtn:RadioButton = e.currentTarget as RadioButton;
			/*if (_tileList != null)
			{
				if (_tileList.parent != null)
				{
					_tileList.parent.removeChild(_tileList);
				}else
				{
					ErrorsCollector.getInstance().collectError("Module bottom: tileList exist, but parent null");
					return;
				}
			}*/
			
			if (radBtn == null)
			{
				ErrorsCollector.getInstance().collectError("Module bottom: radiobutton on click is NULL");
				return;
			}
			var textureGroupe:TextureInfoGroupe = radBtn.value as TextureInfoGroupe;
			if (textureGroupe == null)
			{
				ErrorsCollector.getInstance().collectError("Module bottom: radiobutton on click. textureGroupe is NULL");
				return;
			}
			
			showTextureTileList(textureGroupe);
			
		}
		
		private function showTextureTileList(textureGroupe:TextureInfoGroupe):void {
			
			if (_currentTextureGroupeInfo != null &&
				_currentTextureGroupeInfo == textureGroupe) {
					
					_tileList.visible = true;
					_scrollBar.visible = true;
					return;
			}
			
			_currentTextureGroupeInfo = textureGroupe;
			
			var dp:DataProvider = new DataProvider();
			
			if(_tileList == null){
				_tileList = new TileList();
			}
			
			_tileList.columnWidth = textureGroupe.previewWidth;
			_tileList.rowHeight = textureGroupe.previewHeight;
			_tileList.allowMultipleSelection = false;
			//_tileList.setRendererStyle("contentPadding ", 25);
			_tileList.direction = textureGroupe.displayType == DisplayType.HORIZ_SCROLL ? 
															SliderDirection.HORIZONTAL:
															SliderDirection.VERTICAL;
			if ( textureGroupe.displayType == DisplayType.HORIZ_SCROLL) {
				_tileList.columnWidth += 15;
			}
			var texturesHolderWidth:Number = 650;
			var texturesHolderHeight:Number = 200;
			
			if (textureGroupe.displayType == ScrollBar.VERTICAL)
			{
				_tileList.width = StyleFactory.TEXTURES_LIST_VERTICAL_W;
				_tileList.height = StyleFactory.TEXTURES_LIST_VERTICAL_H;
			}else
			{
				_tileList.width = StyleFactory.TEXTURES_LIST_HORIZ_W;
				_tileList.height = StyleFactory.TEXTURES_LIST_HORIZ_H;
			}
			
			_tileList.x = StyleFactory.BOTTOM_MODULE_WIDTH - texturesHolderWidth + 
							(texturesHolderWidth - _tileList.width) * 0.5;
			_tileList.y = StyleFactory.BOTTOM_MODULE_HEAD_HEIGHT + 
							(texturesHolderHeight - _tileList.height) *0.5;
			_tileList.dataProvider = dp;
			addChild(_tileList);
			_tileList.verticalScrollPolicy = ScrollPolicy.OFF;
			_tileList.horizontalScrollPolicy = ScrollPolicy.OFF;
			_tileList.scrollPolicy = ScrollPolicy.OFF;
			//dp.addItem( { label: e.fileName, source: boxToAdd } );
			// TODO remove listeners _tileList
			_tileList.addEventListener(Event.CHANGE, handleTileListChange);
			//_tileList.addEventListener(ScrollEvent.SCROLL, handleTileListScroll);
			
			
			var itemsCount:int = 0;
			for each(var textureInf:TextureInfo in textureGroupe.textures)
			{
				//var preview:Shape = new Shape();
				var pr:DisplayObject = Images.getInstance().getTexturePreview(textureInf, textureGroupe);
				
				/*if (textureInf.texture != null)
				{
					preview.graphics.beginBitmapFill(textureInf.texture, null, true, true);
				}else if (!isNaN(textureInf.color))
				{
					preview.graphics.beginFill(textureInf.color,1);
				}else
				{
					handleError("Init texture: no color or texture");
					continue;
				}
				preview.graphics.drawRect(0, 0, 80, 80);
				preview.graphics.endFill();*/
				dp.addItem( { label: textureInf.name, source: pr, data:textureInf } );
				itemsCount++;
			}
			//_tileList.setRendererStyle("imagePadding", 25);
			_tileList.dataProvider = dp;
			
			// create scroll bar
			if (_scrollBar!=null && _scrollBar.parent != null)
			{
				_scrollBar.parent.removeChild(_scrollBar);
			}
			
			_scrollBar = new ScrollBar();
			if (textureGroupe.displayType == ScrollBar.VERTICAL)
			{
				StyleFactory.setScrollBarStyle(_scrollBar, StyleFactory.SCROLLBAR_BOTTOM_VERTICAL);
				setupVerticalScrollStep(textureGroupe, itemsCount);
				_scrollBar.x = _tileList.x + _tileList.width - _scrollBar.width;
				_scrollBar.y = StyleFactory.BOTTOM_MODULE_HEAD_HEIGHT + 
							((StyleFactory.BOTTOM_MODULE_HEIGHT - StyleFactory.BOTTOM_MODULE_HEAD_HEIGHT) -
							_scrollBar.height) * 0.5;
			}else
			{
				StyleFactory.setScrollBarStyle(_scrollBar, StyleFactory.SCROLLBAR_BOTTOM_HORIZNTAL);
				setupHorizontalScrollStep(textureGroupe, itemsCount);
				_scrollBar.x = _textureBackground.x + (_textureBackground.width - _scrollBar.width) * 0.5;
				_scrollBar.y = _textureBackground.y + (_textureBackground.height - _scrollBar.height) * 0.5;
			}
			addChild(_scrollBar);
			// bind tile list and scroll bar
			_binderScrollBar.bind(_tileList, _scrollBar, _scrollBar.type);
			//_tileList.setRendererStyle("imagePadding", 10);
			
			_tileList.visible = true;
			_scrollBar.visible = true;
		}
		
		private function setupHorizontalScrollStep(textureGroupe:TextureInfoGroupe, itemsCount:int):void 
		{
			if (_tileList.maxHorizontalScrollPosition == 0)
			{
				_scrollBar.scrollStep = 0;
				return;
			}
			var linesPerFrame:Number = 0.2;
			var itemW:Number = _tileList.maxHorizontalScrollPosition / itemsCount;
			var linePercent:Number = itemW / _tileList.maxHorizontalScrollPosition;
			_scrollBar.scrollStep = linePercent * linesPerFrame;
		}
		
		private function setupVerticalScrollStep(textureGroupe:TextureInfoGroupe, itemsCount:int):void
		{
			var itemsInRow:int = Math.floor(_tileList.width / textureGroupe.previewWidth);
			var linesCount:Number = Math.floor(itemsCount / itemsInRow) + 1;
			//var scrollFactor:Number = _tileList.maxVerticalScrollPosition / linesCount;
			var linesPerFrame:Number = 0.1;
			var lineH:Number = _tileList.maxVerticalScrollPosition / linesCount;
			var linePercent:Number = lineH / _tileList.maxVerticalScrollPosition;
			_scrollBar.scrollStep = linePercent * linesPerFrame;
			//	_scrollBar.scrollStep = 0.002;
		}
		
		private function handleTileListScroll(e:ScrollEvent):void 
		{
			trace("scroll");
		}
		
		private function getSliderDirection():void
		{
			
		}
		
		private function handleTileListChange(e:Event):void 
		{
			if (_tileList.selectedItem == null)
			{
				ErrorsCollector.getInstance().collectError("Module bottom: texture on click. selected item is NULL");
				return;
			}
			var textureInf:TextureInfo = _tileList.selectedItem.data as TextureInfo;
			if (textureInf == null)
			{
				ErrorsCollector.getInstance().collectError("Module bottom: texture on click. textureInf is NULL");
				return;
			}
			
			var currentTextureGroupe:TextureInfoGroupe = getTextureGroupeSelected();
			if (currentTextureGroupe != null)
			{
				
				//_model.paletteProvider.setupPalette(currentTextureGroupe, textureInf);
				dispatchEvent(new ModuleBottomEvent(ModuleBottomEvent.TEXTURE_SELECTED,
													textureInf, currentTextureGroupe));
				
			}else
			{
				
			}
			
			/*if (_btnFacadeChoose.selected)
			{
				_model.currentFacadeTexture = textureInf;
			}else if (_btnTabletopChoose.selected)
			{
				_model.currentTabletopTexture = textureInf;
			}else
			{
				ErrorsCollector.getInstance().collectError("Module bottom: texture on click. unknow category button type");
				return;
			}*/
		}
		
		private function log(msg:String):void
		{
			Logger.log(this, msg);
		}
		
		private function handleError(err:String):void 
		{
			ErrorsCollector.collectError("Module bottom: " + err);
		}
		
		public function get moduleWidth():Number 
		{
			return _moduleWidth;
		}
		
		public function set moduleWidth(value:Number):void 
		{
			_moduleWidth = value;
		}
		
		public function get moduleHeight():Number 
		{
			return _moduleHeight;
		}
		
		public function set moduleHeight(value:Number):void 
		{
			_moduleHeight = value;
		}
		
		
	}

}